package com.yubest.springboothello.interceptors;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 另外一种实现方式，实现 @see CommonsRequestLoggingFilter
 *
 * @Author: hweiyu
 * @Description: 请求响应日志记录
 * @Date: 2024/11/8 10:46
 */
@Component
@Slf4j
public class LogFilter extends OncePerRequestFilter {

    private ObjectMapper mapper = new ObjectMapper();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);

        filterChain.doFilter(requestWrapper, responseWrapper);

        // 记录日志
        log(requestWrapper, responseWrapper);

        // 返回结果发送到客户端
        responseWrapper.copyBodyToResponse();
    }

    private void log(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response) {
        try {
            log.info("------------------Log start--------------------");
            log.info("[REQUEST_URL] : {}, {}", request.getMethod(), request.getRequestURL().toString());
            log.info("[REQUEST_QUERY] : {}", mapper.writeValueAsString(request.getParameterMap()));
            log.info("[REQUEST_BODY] : {}", new String(request.getContentAsByteArray()));
            log.info("[RESPONSE_BODY] : {}", new String(response.getContentAsByteArray()));
            log.info("------------------Log end--------------------");
        } catch (Exception e) {
            log.error("记录日志失败：{}", e.getMessage(), e);
        }
    }
}
